package com.jourwon.spring.boot.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.jourwon.spring.boot.enums.ResponseCodeEnum;
import com.jourwon.spring.boot.query.QueryPageInfo;
import com.jourwon.spring.boot.query.UserQuery;
import com.jourwon.spring.boot.response.ResponsePageInfo;
import com.jourwon.spring.boot.response.ResponseStatus;
import com.jourwon.spring.boot.vo.UserObject;
import com.jourwon.spring.boot.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户controller,使用restful规范
 *
 * @author JourWon
 * @date 2021/1/24
 */
@Api(tags = "用户")
@ApiSupport(author = "JourWon@163.com")
@RestController
@RequestMapping("/user")
public class UserController {

    private static final List<UserVO> LIST = new ArrayList<UserVO>() {
        {
            add(UserVO.builder()
                    .userId(1L).username("JourWon").mobilePhoneNumber("13800000000")
                    .email("JourWon@163.com").deleteState((short) 0)
                    .createTime(LocalDateTime.now()).updateTime(null)
                    .build());
            add(UserVO.builder()
                    .userId(2L).username("Jobs").mobilePhoneNumber("13800000055")
                    .email("Jobs@163.com").deleteState((short) 0)
                    .createTime(LocalDateTime.now()).updateTime(null)
                    .build());
            add(UserVO.builder()
                    .userId(3L).username("Bill Gates").mobilePhoneNumber("13800000066")
                    .email("Bill Gates@163.com").deleteState((short) 0)
                    .createTime(LocalDateTime.now()).updateTime(null)
                    .build());
            add(UserVO.builder()
                    .userId(4L).username("Buffett").mobilePhoneNumber("13800000077")
                    .email("Buffett@163.com").deleteState((short) 0)
                    .createTime(LocalDateTime.now()).updateTime(null)
                    .build());
        }
    };

    @ApiOperationSupport(order = 1)
    @GetMapping("/{userId}")
    @ApiOperation("根据用户ID查询用户")
    public ResponseStatus<UserVO> get(@PathVariable("userId") Long userId) {
        for (UserVO userVO : LIST) {
            if (userId.equals(userVO.getUserId())) {
                return ResponseStatus.success(userVO);
            }
        }

        return ResponseStatus.failure(ResponseCodeEnum.USER_ID_NOT_EXIST);
    }

    @ApiOperationSupport(order = 2)
    @GetMapping
    @ApiOperation("查询所有用户列表")
    public ResponseStatus<UserObject> list() {
        return ResponseStatus.success(new UserObject(LIST));
    }

    @ApiOperationSupport(order = 3)
    @PostMapping("/page")
    @ApiOperation("分页查询用户列表")
    public ResponseStatus<ResponsePageInfo<UserVO>> page(@Valid @RequestBody QueryPageInfo<UserQuery> queryPageInfo) {
        List<UserVO> userList = new ArrayList<>();

        // 此处多条件模糊查询有问题，只做演示使用
        List<UserVO> conditionUserList = new ArrayList<>();
        UserQuery condition = queryPageInfo.getCondition();
        if (Objects.nonNull(condition)) {
            List<UserVO> list = new ArrayList<>();
            for (UserVO userVO : LIST) {
                String username = condition.getUsername();
                String mobilePhoneNumber = condition.getMobilePhoneNumber();
                String email = condition.getEmail();
                if (StringUtils.isNotBlank(username)) {
                    if (userVO.getUsername().contains(username)) {
                        list.add(userVO);
                    }
                }

                if (StringUtils.isNotBlank(mobilePhoneNumber)) {
                    if (userVO.getMobilePhoneNumber().contains(mobilePhoneNumber)) {
                        list.add(userVO);
                    }
                }

                if (StringUtils.isNotBlank(email)) {
                    if (userVO.getEmail().contains(email)) {
                        list.add(userVO);
                    }
                }
            }

            if (CollectionUtils.isEmpty(list)) {
                list = LIST;
            }

            conditionUserList = list.stream().collect(
                    Collectors.collectingAndThen(
                            Collectors.toCollection(() ->
                                    new TreeSet<>(Comparator.comparing(UserVO::getUserId))), ArrayList::new));
        }

        int pageSize = queryPageInfo.getPageSize();
        int pageNum = queryPageInfo.getPageNo();

        int size = conditionUserList.size();
        int start = (pageNum - 1) * pageSize;
        int end = Math.min(pageNum * pageSize, size);

        for (int i = start; i < end; i++) {
            userList.add(conditionUserList.get(i));
        }

        int pages = (size + pageSize - 1) / pageSize;
        ResponsePageInfo<UserVO> page = new ResponsePageInfo<>(pageNum,
                pageSize, userList.size(), pages, (long) size, userList);

        return ResponseStatus.success(page);
    }

    @ApiOperationSupport(order = 4)
    @PostMapping
    @ApiOperation("新增用户")
    public ResponseStatus insert(@Valid @RequestBody UserQuery userQuery) {
        Optional<UserVO> optional = LIST.stream().max(Comparator.comparing(UserVO::getUserId));
        UserVO userVO = null;
        if (optional.isPresent()) {
            userVO = UserVO.builder().userId(optional.get().getUserId() + 1L).username(userQuery.getUsername())
                    .mobilePhoneNumber(userQuery.getMobilePhoneNumber()).email(userQuery.getEmail())
                    .deleteState((short) 0).createTime(LocalDateTime.now()).updateTime(null).build();
        }
        LIST.add(userVO);
        return ResponseStatus.success();
    }

    @ApiOperationSupport(order = 5)
    @PutMapping("/{userId}")
    @ApiOperation("根据用户ID更新用户")
    public ResponseStatus update(@PathVariable("userId") Long userId, @Valid @RequestBody UserQuery userQuery) {
        for (UserVO userVO : LIST) {
            if (userId.equals(userVO.getUserId())) {
                userVO.setUsername(userQuery.getUsername());
                userVO.setMobilePhoneNumber(userQuery.getMobilePhoneNumber());
                userVO.setEmail(userQuery.getEmail());
                userVO.setUpdateTime(LocalDateTime.now());
                return ResponseStatus.success();
            }
        }

        return ResponseStatus.failure(ResponseCodeEnum.USER_ID_NOT_EXIST);
    }

    @ApiOperationSupport(order = 6)
    @DeleteMapping("/{userId}")
    @ApiOperation("根据用户ID删除用户")
    public ResponseStatus delete(@PathVariable("userId") Long userId) {
        Iterator<UserVO> iterator = LIST.iterator();
        while (iterator.hasNext()) {
            if (userId.equals(iterator.next().getUserId())) {
                iterator.remove();
                return ResponseStatus.success();
            }
        }

        return ResponseStatus.failure(ResponseCodeEnum.USER_ID_NOT_EXIST);
    }

}
